#include <iostream>
#include <string>
#include "head.h"

using namespace std;

/* 函数模板:显示类型指定时，能够进行隐式类型转换 */
class Test
{
    Test(const Test&);
public:
    Test()
    {

    }
};
template < typename T >
void Swap(T& a, T& b)
{
    T c = a;
    a = b;
    b = c;
}

typedef void(FunI)(int&, int&);
typedef void(FunD)(double&, double&);
typedef void(FunT)(Test&, Test&);
int test1()
{
    /* 编译器自动推导 T 为 int */
    FunI* pi = Swap;

    /* 编译器自动推导 T 为 double */
    FunD* pd = Swap;

    /* 编译器自动推导 T 为 Test */
    //FunT* pt = Swap;

    /* reinterpret_cast 强制类型转换：用于指针类型间的强制转换，用于整型和指针间的强制转换*/
    cout << "pi = " << reinterpret_cast<void*>(pi) << endl;
    cout << "pd = " << reinterpret_cast<void*>(pd) << endl;
    //cout << "pt = " << reinterpret_cast<void*>(pt) << endl;

    return 0;
}

/* 多参数的函数模板 */

template
< typename T1, typename T2, typename T3 >
T1 Add(T2 a, T3 b)
{
    return static_cast<T1>(a + b);
}

int test2()
{
    int r1 = Add<int>(0.5, 0.8);

    double r2 = Add<double, double>(0.5, 0.8);

    float r3 = Add<float, float, float>(0.5, 0.8);

    cout << "r1 = " << r1 << endl;
    cout << "r2 = " << r2 << endl;
    cout << "r3 = " << r3 << endl;

    return 0;
}


/* 重载函数模板 */

template < typename T >
T Max(T a, T b)
{
    cout << "T Max(T a, T b)" << endl;

    return a > b ? a : b;
}

int Max(int a, int b)
{
    cout << "int Max(int a, int b)" << endl;
    return a > b ? a : b;
}

template < typename T >
T Max(T a, T b, T c)
{
    cout << "T Max(T a, T b, T c)" << endl;

    return Max(Max(a, b), c);
}

template
< typename T >
bool Equal(T a, T b)
{
    cout << "bool Equal(T a, T b)" << endl;
    return  a == b;
}

/* 函数模板的特化 ：只能完全特化 */
template
<  >
bool Equal<double>(double a, double b)
{
    const double delta = 0.00000000000001;
    double r = a - b;

    cout << "bool Equal<double>(double a, double b)" << endl;

    return (-delta < r) && (r < delta);
}

bool Equal(double a, double b)
{
    const double delta = 0.00000000000001;
    double r = a - b;

    cout << "bool Equal(double a, double b)" << endl;

    return (-delta < r) && (r < delta);
}

int func_mode_test(void)
{
    int a = 1;
    int b = 2;

    /* 普通函数 */
    cout << Max(a, b) << endl;

    /* 函数模板 */
    cout << Max<>(a, b) << endl;

    /* 函数模板 */
    cout << Max(3.0, 4.0) << endl;

    /* 函数模板 */
    cout << Max(5.0, 6.0, 7.0) << endl;

    /* 应为函数模板不支持类型转换，故调用普通函数 */
    cout << Max('a', 100) << endl;

    cout << Equal(1, 1) << endl;
    cout << Equal<>(0.001, 0.001) << endl;
    cout << Equal(0.001, 0.001) << endl;
    return 0;
}
